`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: 
// 
// Create Date:    00:51:24 04/24/2011 
// Design Name: 
// Module Name:    FSM 
// Project Name: 
// Target Devices: 
// Tool versions: 
// Description: 
//
// Dependencies: 
//
// Revision: 
// Revision 0.01 - File Created
// Additional Comments: 
//
//////////////////////////////////////////////////////////////////////////////////
module playNote(clk, enableSound, reset, note);

//
input clk;
input reset;
input enableSound;
output note;

//
reg note;
reg [3:0] Ps;
reg [3:0] Ns;
reg [31:0] length;
reg [7:0] nextNote;

//
parameter fourth = 12500000;
parameter sixth = 8160000;

//notes precets, defaults are in C'4' octave
parameter Cn4 = 4'b0001;//C4 enabled
parameter Dn4 = 4'b0010;//D4 enabled
parameter En4 = 4'b0011;//E4 enabled
parameter Fn4 = 4'b0100;//F4 enabled
parameter Gn4 = 4'b0101;//G4 enabled
parameter An4 = 4'b0110;//A4 enabled
parameter Bn4 = 4'b0111;//B4 enabled

//notes precets, defaults are in C'5' octave
parameter Cn5 = 4'b1000;//C5 enabled
parameter Dn5 = 4'b1001;//D5 enabled
parameter En5 = 4'b1010;//E5 enabled
parameter Fn5 = 4'b1011;//F5 enabled
parameter Gn5 = 4'b1100;//G5 enabled
parameter An5 = 4'b1110;//A5 enabled
parameter Bn5 = 4'b1111;//B5 enabled
parameter noSound = 1'b0;

// 4

clkDivider C4(clk, C4clk, reset); //C4
//defparam     C4.BITS = 32;
defparam       C4.maxcount = 191109; //answers rounded up/down
//defparam   C4.maxcount = 1; // for testing

clkDivider D4(clk, D4clk, reset); //D4
//defparam     D4.BITS = 32;
defparam       D4.maxcount = 170264; //answers rounded up/down
//defparam   D4.maxcount = 1; // for testing

clkDivider E4(clk, E4clk, reset); //E4
//defparam     E4.BITS = 32;
defparam       E4.maxcount = 151685; //answers rounded up/down
//defparam   E4.maxcount = 1; // for testing

clkDivider F4(clk, F4clk, reset); //F4
//defparam     F4.BITS = 32;
defparam       F4.maxcount = 143172; //answers rounded up/down
//defparam   F4.maxcount = 1; // for testing

clkDivider G4(clk, G4clk, reset); //G4
//defparam     G4.BITS = 32;
defparam       G4.maxcount = 127551; //answers rounded up/down
//defparam   G4.maxcount = 1; // for testing

clkDivider A4(clk, A4clk, reset); //A4
//defparam     A4.BITS = 32;
defparam       A4.maxcount = 113636; //answers rounded up/down
//defparam   A4.maxcount = 1; // for testing

clkDivider B4(clk, B4clk, reset); //B4
//defparam     B4.BITS = 32;
defparam       B4.maxcount = 101239; //answers rounded up/down
//defparam   B4.maxcount = 1; // for testing

// 5

clkDivider C5(clk, C5clk, reset); //C5
//defparam     Cn5.BITS = 32;
defparam       Cn5.maxcount = 95556; //answers rounded up/down
//defparam   Cn5.maxcount = 1; // for testing

clkDivider D5(clk, D5clk, reset); //D5
//defparam     Dn5.BITS = 32;
defparam       Dn5.maxcount = 85.131; //answers rounded up/down
//defparam   Dn5.maxcount = 1; // for testing

clkDivider E5(clk, E5clk, reset); //E5
//defparam     E5.BITS = 32;
defparam       E5.maxcount = 75842; //answers rounded up/down
//defparam   E5.maxcount = 1; // for testing

clkDivider F5(clk, F5clk, reset); //F5
//defparam     F5.BITS = 32;
defparam       F5.maxcount = 71586; //answers rounded up/down
//defparam   F5.maxcount = 1; // for testing

clkDivider G5(clk, G5clk, reset); //G5
//defparam     G5.BITS = 32;
defparam       G5.maxcount = 63776; //answers rounded up/down
//defparam   G5.maxcount = 1; // for testing

clkDivider A5(clk, A5clk, reset); //A5
//defparam     A5.BITS = 32;
defparam       A5.maxcount = 56818; //answers rounded up/down
//defparam   A5.maxcount = 1; // for testing

clkDivider B5(clk, B5clk, reset); //B5
//defparam     B5.BITS = 32;
defparam       B5.maxcount = 50619; //answers rounded up/down
//defparam   B5.maxcount = 1; // for testing

// Comments
always@(posedge clk) begin
if(reset)
	Ps <= noSound;
else
	Ps <= Ns;
end
//Next state selector
always @(posedge clk) begin
 if(reset) nextNote <= 0;
 else begin
		case(nextNote)
			0: begin 
				Ns <= noSound; //Rest, 1
				if(length < 1)begin//if reached note length to play continue to next note
					nextNote <= nextNote+1;
					length <= fourth; //Sets nexts state!
					//$display("Going to State 2 ctl = %b SongState = %b Length = %d, NOTE = %b", ctl, song, length, note);
				end
				else
					length <= length - counter;
			end
			1: begin 
				Ns <= C4; //C4
				if(length < 1)begin//if reached note length to play continue to next note
					nextNote <= nextNote+1;
					length <= fourth; //Sets nexts state!
				end
				else
					length <= length - counter;
			end
			2: begin //if(length == one || length < 1)
				Ns <= D4; //D4
				if(length < 1)begin//if reached note length to play continue to next note
					nextNote <= nextNote+1;
					length <= fourth; //Sets nexts state!
				end
				else
					length <= length - counter;
			end
			3: begin //if(length == one || length < 1)
				Ns <= E4; //E4, .33
				if(length < 1)begin//if reached note length to play continue to next note
					nextNote <= nextNote+1;
					length <= fourth; //Sets nexts state!
				end
				else
					length <= length - counter;
			end
			4: begin  
			Ns <= F4; //F4
				if(length < 1)begin//if reached note length to play continue to next note
					nextNote <= nextNote+1;
					length <= fourth; //Sets nexts state!
				end
				else
					length <= length - counter;
			end
			5: begin  if(length == one || length < 1)
				Ns <= G4; //G4
				if(length < 1)begin//if reached note length to play continue to next note
					nextNote <= nextNote+1;
					length <= fourth; //Sets nexts state!
				end
				else
					length <= length - counter;
			end
			6: begin//if(length == one || length < 1) begin
				Ns <= A4; //A4
				if(length < 1)begin//if reached note length to play continue to next note
					nextNote <= nextNote+1;
					length <= fourth; //Sets nexts state!
				end
				else
					length <= length - counter;
			end
			7: begin//if(length == one || length < 1) begin
				Ns <= B4; //B4
				if(length < 1)begin//if reached note length to play continue to next note
					nextNote <= nextNote+1;
					length <= fourth; //Sets nexts state!
				end
				else
					length <= length - counter;
			end
			8: begin//if(length == one || length < 1) begin
				Ns <= C5; //C5
				if(length < 1)begin//if reached note length to play continue to next note
					nextNote <= nextNote+1;
					length <= fourth;//Sets nexts state!
				end
				else
					length <= length - counter;
			end
			8: begin//if(length == one || length < 1) begin
				Ns <= D5; //D5
				if(length < 1)begin//if reached note length to play continue to next note
					nextNote <= nextNote+1;
					length <= fourth;//Sets nexts state!
				end
				else
					length <= length - counter;
			end
			9: begin //if(length == one || length < 1)
				Ns <= E5; //E5
				if(length < 1)begin//if reached note length to play continue to next note
					nextNote <= nextNote+1;
					length <= fourth; //Sets nexts state!
				end
				else
					length <= length - counter;
			end
			10: begin//if(length == one || length < 1) begin
				Ns <= F5; //F5
				if(length < 1)begin//if reached note length to play continue to next note
					nextNote <= nextNote+1;
					length <= fourth; //Sets nexts state!
				end
				else
					length <= length - counter;
			end
			11: begin //if(length == one || length < 1)
				Ns <= G5; //G5
				if(length < 1)begin//if reached note length to play continue to next note
					nextNote <= nextNote+1;
					length <= fourth; //Sets nexts state!
				end
				else
					length <= length - counter;
			end
			12: begin //if(length == one || length < 1)
				Ns <= A5; //A5
				if(length < 1)begin//if reached note length to play continue to next note
					nextNote <= nextNote+1;
					length <= fourth; //Sets nexts state!
				end
				else
					length <= length - counter;
			end
			13: begin //if(length == one || length < 1)
				Ns <= B5; //B5
				if(length < 1)begin//if reached note length to play continue to next note
					nextNote <= nextNote+1;
					length <= fourth; //Sets nexts state!
				end
				else
					length <= length - counter;
			end
			default: begin 
				Ns <= noSound; //replay song
				nextNote <= 6'b000000;
				length <= fourth; //first note length
				end //restart
		endcase
		end
	end
//Note Selector
always @(*) begin
	case(Ps)
		Cn4: note <= C4clk; //Play C4
		Dn4: note <= D4clk; //Play D4
		En4: note <= E4clk; //Play E4
		Fn4: note <= F4clk; //Play F4
		Gn4: note <= G4clk; //Play G4
		An4: note <= A4clk; //Play A4
		Bn4: note <= B4clk; //Play B4
		Cn5: note <= C5clk; //Play C5
		Dn5: note <= D5clk; //Play D5
		En5: note <= E5clk; //Play E5
		Fn5: note <= F5clk; //Play F5
		Gn5: note <= G5clk; //Play G5
		An5: note <= A5clk; //Play A5
		Bn5: note <= B5clk; //Play B5
		default: begin // no sound
			note <= noSound;
	end
	endcase
end
endmodule

